import * as path from "path";
import * as fs from "fs";
import { Logger } from '../src/logger/Logger';

// 动态加载 web-tree-sitter 以避免打包问题
// 在运行时加载可以确保 __filename 可用
const getTreeSitterModule = () => {
    try {
        // 使用 require 动态加载，这样 web-tree-sitter 内部的 __filename 会正确解析
        const TreeSitterModule = require('web-tree-sitter');
        
        // 尝试多种导出方式
        if (TreeSitterModule.Parser && typeof TreeSitterModule.Parser.init === 'function') {
            return TreeSitterModule;
        }
        if (TreeSitterModule.default?.Parser && typeof TreeSitterModule.default.Parser.init === 'function') {
            return TreeSitterModule.default;
        }
        if (typeof TreeSitterModule.init === 'function') {
            return { Parser: TreeSitterModule, Language: TreeSitterModule.Language };
        }
        if (TreeSitterModule.default && typeof TreeSitterModule.default.init === 'function') {
            return { Parser: TreeSitterModule.default, Language: TreeSitterModule.default.Language };
        }
        
        throw new Error('Unable to load web-tree-sitter. Available keys: ' + Object.keys(TreeSitterModule).join(', '));
    } catch (error) {
        Logger.error(`Failed to require web-tree-sitter: ${error}`);
        throw error;
    }
};

const TreeSitter = getTreeSitterModule();
const Parser = TreeSitter.Parser;

let setedPath = '';

export function getBaseDir(): string {
    if (setedPath === '') {
        try {
            return __dirname;
        } catch {
            return process.cwd();
        }
    } else {
        return setedPath;
    }
}

/**
 * TreeSitter解析器管理类
 */
class treeSitterParser {
    private static initPromise: Promise<void> | null = null;
    private static parserInstance = new Map<string, any>();

    public static async initParser(wasmFileName: string): Promise<any> {
        // 确保全局的 Parser.init() 只被调用一次
        if (!this.initPromise) {
            const baseDir = getBaseDir();
            Logger.info(`[Parser.init] Starting initialization, baseDir: ${baseDir}`);
            
            // 预先查找 tree-sitter.wasm 的位置
            let treeSitterWasmPath = '';
            const possiblePaths = [
                path.join(baseDir, 'tools', 'tree-sitter.wasm'),
                path.join(baseDir, 'tree-sitter.wasm'),
                path.join(baseDir, 'node_modules', 'web-tree-sitter', 'tree-sitter.wasm'),
                path.join(baseDir, '..', 'node_modules', 'web-tree-sitter', 'tree-sitter.wasm')
            ];
            
            for (const tryPath of possiblePaths) {
                if (fs.existsSync(tryPath)) {
                    treeSitterWasmPath = tryPath;
                    Logger.info(`[Parser.init] Found tree-sitter.wasm at: ${tryPath}`);
                    break;
                }
            }
            
            if (!treeSitterWasmPath) {
                Logger.error(`[Parser.init] tree-sitter.wasm not found in any of the following paths:`);
                possiblePaths.forEach(p => Logger.error(`  - ${p}`));
                throw new Error('tree-sitter.wasm not found');
            }
            
            // 在 Node.js 环境中，直接使用文件路径初始化
            // 将路径转换为 file:// URL
            const fileUrl = `file://${treeSitterWasmPath.replace(/\\/g, '/')}`;
            Logger.info(`[Parser.init] Using file URL: ${fileUrl}`);
            
            this.initPromise = Parser.init({
                locateFile(scriptName: string, scriptDirectory: string) {
                    console.log(`[locateFile] scriptName: ${scriptName}, scriptDirectory: ${scriptDirectory}`);
                    
                    if (scriptName === 'tree-sitter.wasm') {
                        // 返回绝对路径
                        const result = treeSitterWasmPath;
                        console.log(`[locateFile] Returning: ${result}`);
                        return result;
                    }
                    
                    return path.join(scriptDirectory, scriptName);
                }
            }).catch((error: any) => {
                this.initPromise = null;
                Logger.error(`Failed to initialize Tree-sitter parser: ${error}`);
                Logger.error(`Error stack: ${error.stack}`);
                throw error;
            });
        }

        // 等待全局初始化完成
        await this.initPromise;

        let parser = this.parserInstance.get(wasmFileName);
        if (parser) {
            return parser;
        }

        try {
            // 在开发模式下：__dirname 指向 core 目录，tools 在 ../tools
            // 在打包模式下：__dirname 指向 dist 目录，tools 在 dist/tools
            const baseDir = getBaseDir();
            Logger.info(`[initParser] baseDir: ${baseDir}, wasmFileName: ${wasmFileName}`);
            
            let extensionPath = path.join(baseDir, 'tools');
            Logger.info(`[initParser] Trying extensionPath: ${extensionPath}`);
            
            // 如果 tools 不存在，尝试上一级目录（开发模式）
            if (!fs.existsSync(extensionPath)) {
                extensionPath = path.join(baseDir, '..', 'tools');
                Logger.info(`[initParser] Tools not found, trying parent: ${extensionPath}`);
            }
            
            const pathLang = path.join(extensionPath, wasmFileName);
            Logger.info(`Loading tree-sitter WASM from: ${pathLang}`);
            
            // 使用 TreeSitter 模块中的 Language 类
            const Language = TreeSitter.Language || Parser.Language;
            if (!Language) {
                throw new Error('Language class not found in web-tree-sitter module');
            }
            
            const lang = await Language.load(pathLang);

            parser = new Parser();
            parser.setLanguage(lang);

            this.parserInstance.set(wasmFileName, parser);
            return parser;
        } catch (error) {
            Logger.error(`Failed to load language ${wasmFileName}: ${error}`);
            throw error;
        }
    }
}

// 导出initParser函数以保持向后兼容
export async function initParser(wasmFileName: string): Promise<any> {
    return treeSitterParser.initParser(wasmFileName);
}

// 导出 Parser 类型
export { Parser };
